using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Collections.Specialized;
using System.Windows.Forms;
using GraphConstructor;
using System.ComponentModel;

namespace GraphConstructor
{
    [Serializable]
    public abstract class ShapeBase
    {
        #region DataMembers
        private Color _selectedColor = Color.White;
        private Color _backColor;
        private bool _isSelected;
        private bool _isShiftPressed;
        [NonSerialized]
        private Bitmap _renderedImage;
        [NonSerialized]
        private Pen _drawingPen;
        [NonSerialized]
        private Pen _selectedDrawingPen;
        private bool _isDragging = false;
        private Point _lastPoint;
        private bool _isBold = false;
        protected string _id;
        private int _left;
        private int _top;
        private int _width;
        private int _height;

        #endregion
        
        #region Properties
        [Browsable(false)]
        public bool IsBold
        {
            get { return _isBold; }
            set { _isBold = value; }
        }
        public Color BackColor
        {
            get { return _backColor; }
            set
            {
                _backColor = value;
                OnRedrawRequest(new EventArgs());
            }
        }
        [Category("Orientation")]
        public int Top
        {
            get { return _top; }
            set { _top = value; }
        }
        [Category("Orientation")]
        public int Left
        {
            get { return _left; }
            set { _left = value; }
        }
        [Category("Orientation")]
        public Point Location
        {
            get { return new Point(Left, Top); }
            set
            {
                Left = value.X;
                Top = value.Y;
            }
        }
        [Category("Orientation")]
        public int Width
        {
            get { return _width; }
            set
            {
                _width = value;
                OnRedrawRequest(new EventArgs());
            }
        }
        [Category("Orientation")]
        public int Height
        {
            get { return _height; }
            set
            {
                _height = value;
                OnRedrawRequest(new EventArgs());
            }
        }
        [Browsable(false)]
        public int ScaledWidth
        {
            get { return Width - 13; }
        }
        [Browsable(false)]
        public int ScaledHeight
        {
            get { return Height - 13; }
        }
        [Browsable(false)]
        public Pen DrawingPen
        {
            get
            {
                if (_drawingPen == null)
                    _drawingPen = new Pen(Brushes.Black);
                return _drawingPen;
            }
            set { _drawingPen = value; }
        }
        [Browsable(false)]
        public Pen SelectedDrawingPen
        {
            get
            {
                if (_selectedDrawingPen == null)
                    _selectedDrawingPen = new Pen(Brushes.Blue);
                return _selectedDrawingPen;
            }
            set { _selectedDrawingPen = value; }
        }
        [Browsable(false)]
        public Bitmap RenderedImage
        {
            get
            {
                if (_renderedImage == null)
                    _renderedImage = new Bitmap(50, 50);
                return _renderedImage;
            }
            set { _renderedImage = value; }
        }
        [Browsable(false)]
        public bool IsSelected
        {
            get { return _isSelected; }
            set { _isSelected = value; }
        }
        public string ID
        {
            get { return _id; }
            set
            {
                _id = value;
                OnRedrawRequest(new EventArgs());
            }
        }
        //public Color BackColor
        //{
        //    get { return _backColor; }
        //    set { _backColor = value; }
        //}        
        //public Color ForeColor
        //{
        //    get { return _foreColor; }
        //    set { _foreColor = value; }
        //}
        public Color SelectedColor
        {
            get { return _selectedColor; }
            set { _selectedColor = value; }
        }
        #region Virtual Properties
        [Category("Orientation")]
        public virtual Point Center
        {
            get { return new Point(Location.X + Width / 2, Location.Y + Height / 2); }
        }
        #endregion
        #endregion

        #region Events
        [field:NonSerialized]
        public event EventHandler PositionChanged;
        [field: NonSerialized]
        public event EventHandler RedrawRequest;
        //public event EventHandler Click;
        //public event EventHandler DoubleClick;
        //public event EventHandler RightClick;
        //public event MouseEventHandler MouseDown;
        //public event MouseEventHandler MouseUp;
        //public event MouseEventHandler MouseMove;
        protected void OnRedrawRequest(EventArgs e)
        {
            if (RedrawRequest != null)
                RedrawRequest(this, e);
        }
        protected void OnPositionChanged(EventArgs e)
        {
            if (PositionChanged != null)
                PositionChanged(this, e);
        }
        //protected void OnClick()
        //{
        //    EventArgs e = new EventArgs();
        //    if (Click != null)
        //        Click(this, e);
        //}
        //protected void OnDoubleClick()
        //{
        //    EventArgs e = new EventArgs();
        //    if (DoubleClick != null)
        //        DoubleClick(this, e);
        //}
        //protected void OnRightClick()
        //{
        //    EventArgs e = new EventArgs();
        //    if (RightClick != null)
        //        RightClick(this, e);
            
        //}
        //protected void OnMouseDown(MouseButtons mButtons, int Clicks, int x, int y)
        //{
        //    MouseEventArgs e = new MouseEventArgs(mButtons, Clicks, x, y, 0);
        //    if (MouseDown != null)
        //        MouseDown(this, e);
        //}
        //protected void OnMouseUp(MouseButtons mButtons, int Clicks, int x, int y)
        //{
        //    MouseEventArgs e = new MouseEventArgs(mButtons, Clicks, x, y, 0);
        //    if (MouseUp != null)
        //        MouseUp(this, e);
        //}
        //protected void OnMouseMove(MouseButtons mButtons, int Clicks, int x, int y)
        //{
        //    MouseEventArgs e = new MouseEventArgs(mButtons, Clicks, x, y, 0);
        //    if (MouseMove != null)
        //        MouseMove(this, e);
        //}
        #endregion

        public ShapeBase()
        {
            //RefreshBitmap();
        }
        public void LoadSettings(NameValueCollection settings)
        {
        }
        public void Select()
        {
            _isSelected = true;
            OnRedrawRequest(new EventArgs());
        }
        public void Deselect()
        {
            _isSelected = false;
            OnRedrawRequest(new EventArgs());
        }
        public void MakeBold()
        {
            IsBold = true;
            OnRedrawRequest(new EventArgs());
        }
        public void RemoveBold()
        {
            IsBold = false;
            OnRedrawRequest(new EventArgs());
        }
        #region Abstract Methods
        protected abstract void RefreshBitmap(Graphics g);
        public abstract bool IsInside(Point point);
        public abstract ShapeBase Clone();
        //protected abstract ShapeBase CreateDefault(Point pos);
        #endregion
        #region Override Methods
        public virtual void OnPaint(PaintEventArgs e)
        {
            RefreshBitmap(e.Graphics);
            /*Graphics g = e.Graphics;
            g.Clear(BackColor);
            g.DrawImageUnscaled(RenderedImage, 0, 0);
            */
        }
        public virtual void OnMouseUp(System.Windows.Forms.MouseEventArgs e)
        {
            Select();
            _isDragging = false;
        }
        public virtual void OnMouseMove(MouseEventArgs e)
        {
            if (_isDragging)
            {
                Point p = new Point(e.X, e.Y);
                Point pNew = new Point(p.X - _lastPoint.X, p.Y - _lastPoint.Y);
                //(Parent.Parent as frmMain).strpCoord.Text = "X: " + p.X + ", Y: " + p.Y;
                //Application.DoEvents();
                Left += pNew.X;
                Top += pNew.Y;
                _lastPoint = p;
                OnPositionChanged(new EventArgs());
                OnRedrawRequest(new EventArgs());
            }
        }
        public virtual void OnMouseDown(MouseEventArgs e)
        {
            if (!_isShiftPressed)
            {
                _isDragging = true;
                _lastPoint = new Point(e.X, e.Y);
            }
        }
        public virtual void OnKeyDown(KeyEventArgs e)
        {
            if (e.Shift)
                _isShiftPressed = true;
        }
        public virtual void OnKeyUp(KeyEventArgs e)
        {
            if (e.Shift)
                _isShiftPressed = false;
        }
        #endregion
    }
}
